<template>
    <!-- 权限配置弹窗 -->
    <el-dialog
        title="权限配置"
        :visible="visible"
        width="60%"
        :close-on-click-modal="false"
        :before-close="handleDialogClose"
        append-to-body
    >
        <!-- 添加租户/用户的子弹窗 -->
        <el-dialog
            width="55%"
            :title="`添加${roleFlag}`"
            :visible="innerDialogVisible"
            :close-on-click-modal="false"
            :before-close="handleInnerDialogClose"
            append-to-body>
            <el-form label-width="80px">
                <el-form-item label="资源名称">
                    {{servicePath}}
                </el-form-item>
                <el-form-item :label="`选择${roleFlag}`">
                    <el-select
                        v-model="addSubordinatesForm.subordinates"
                        :placeholder="`请选择${roleFlag}`"
                        multiple
                        filterable
                        :loading="subordinatesLoading"
                        class="select"
                    >
                        <el-option
                            v-for="sub in totalSubordinates.filter(m => !authList.some(a => a.userId === m.userId))"
                            :key="sub.userId"
                            :label="sub.username"
                            :value="sub.userId"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="分配权限">
                    <el-checkbox
                        :indeterminate="addSubordinatesForm.isIndeterminate"
                        v-model="addSubordinatesForm.authoritysCheckAll"
                        @change="handleAddSubAuthorityCheckAllChange"
                        :disabled="!totalAuthoritys.every(t => currentUserAuth.includes(t))"
                    >全选</el-checkbox>
                    <el-checkbox-group v-model="addSubordinatesForm.authoritys" @change="handleAddSubCheckedAuthorityChange">
                        <el-checkbox
                            v-for="a in totalAuthoritys"
                            :key="a"
                            :label="a"
                            name="type"
                            :disabled="!currentUserAuth.some(m => m === a)"
                        />
                    </el-checkbox-group>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="handleInnerDialogClose">取 消</el-button>
                <el-button type="primary" :disabled="!addSubordinatesForm.subordinates.length > 0" @click="handleConformSubordinates">确 定</el-button>
            </span>
        </el-dialog>
        <el-form label-width="80px">
            <div v-if="loading" v-loading="true" class="loading"></div>
            <div v-else-if="isNoRightToAssignAuth" class="no-use-assign-auth">抱歉，您无权这么做，该资源应由对应租户来进行权限配置。</div>
            <template v-else>
                <el-form-item label="资源名称">
                    {{servicePath}}
                </el-form-item>
                <el-form-item :label="`添加${roleFlag}`">
                    <i class="el-icon-plus add-icon" @click="onAddUser"/>
                </el-form-item>
                <el-form-item label="分配权限">
                    <ul class="authList-wrap" v-if="authList && authList.length">
                        <li :class="{'auth-item': authList.length > 1}" v-for="(user, i) in authList" :key="user.userId">
                            <el-form-item :label="getUserFlag(user.role)" label-width="50px">
                                <span>{{ user.userName }}</span>
                                <i v-if="user.id === null" title="删除" class="el-icon-delete" @click="onDeleteItem(i)"></i>
                            </el-form-item>
                            <el-form-item label="权限" label-width="50px">
                                <el-checkbox
                                    :indeterminate="user.auth && user.auth.length > 0 && user.auth.length < totalAuthoritys.length"
                                    v-model="user.authoritysCheckAll"
                                    @change="handleUserAuthorityCheckAllChange(user)"
                                    :disabled="!totalAuthoritys.every(t => currentUserAuth.includes(t))"
                                >全选</el-checkbox>
                                <el-checkbox-group v-model="user.auth">
                                    <el-checkbox
                                        v-for="a in totalAuthoritys"
                                        :key="a"
                                        :label="a"
                                        name="type"
                                        @change="handleUserAuthChange(user)"
                                        :disabled="!currentUserAuth.some(m => m === a)"
                                    />
                                </el-checkbox-group>
                            </el-form-item>
                        </li>
                    </ul>
                    <span v-else>无</span>
                </el-form-item>
            </template>
            
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="handleDialogClose">取 消</el-button>
            <el-button type="primary" :disabled="!hasRealChange" :loading="submiting" @click="handleSubmit">确 定</el-button>
        </span>
    </el-dialog>
</template>
<script>
import { authApi } from '@/request'
import { mapState } from 'vuex'
import { API_ERROR_CODE } from '@/const'
import { 
    MANAGER_ROLE_CODE,
    LOGINER_FLAG_MAP,
    HDFS_AUTHORITYS,
    HBASE_AUTHORITYS,
    HIVE_AUTHORITYS,
    YARN_AUTHORITYS,
    KAFKA_AUTHORITYS
} from '@/const'

const ALL_AUTHORITYS = {
    HDFS: HDFS_AUTHORITYS,
    HBASE: HBASE_AUTHORITYS,
    HIVE: HIVE_AUTHORITYS,
    YARN: YARN_AUTHORITYS,
    KAFKA: KAFKA_AUTHORITYS
}

let SERVICE = 'HDFS'

let ORIGIN_AUTH_LIST = []

export default {
    name: 'authorityDialog',
    props: {
        visible: {
            type: Boolean,
            default: false
        },
        currentRow: {
            type: Object,
            default: {}
        },
        servicePath: {
            type: String,
            default: ''
        }
    },
    data() {
        return {
            loading: false,
            subordinatesLoading: false,
            // 权限分配列表
            authList: [],
            // 临时添加的租户/用户权限分配（这时不同租户/用户权限一致）
            addSubordinatesForm: {
                subordinates: [],
                authoritys: [],
                authoritysCheckAll: false,
                isIndeterminate: false
            },
            // 总的下属成员列表
            totalSubordinates: [],
            // 总的权限列表
            totalAuthoritys: [],
            // 当前用户拥有的权限列表
            currentUserAuth: [],
            // 是否正在提交
            submiting: false,
            // 内层对话框是否显示
            innerDialogVisible: false,
            roleFlag: '',
            // 无权这么做，该资源应由对应租户来进行权限配置
            isNoRightToAssignAuth: false
        }
    },
    computed: {
        ...mapState(['loginerRole', 'loginerUserId']),
        // 是否真的更改了权限配置
        hasRealChange() {
            let flag = false
            // 过滤一下当前的authList
            const currAuthList = this.authList.filter(item => item.auth && item.auth.length > 0)
            // 如果length不同，直接返回true
            if (currAuthList.length !== ORIGIN_AUTH_LIST.length) {
                flag = true
                return flag
            }
            // 循环遍历，对比，
            for (let i = 0, len = ORIGIN_AUTH_LIST.length; i < ORIGIN_AUTH_LIST.length; i++) {
                const item = ORIGIN_AUTH_LIST[i] || {}
                const userId = item.userId
                const auth = item.auth || []
                const newItem = currAuthList.find(m => m.userId === userId) || {}
                const newAuth = newItem.auth || []
                // length不同，返回true
                if (newAuth.length !== auth.length) {
                    flag = true
                    break
                } 
                // 如果newAuth有一项不在auth中，则返回true
                else if (newAuth.some(n => !auth.includes(n))) {
                    flag = true
                    break
                }
            }
            return flag
        }
    },
    created() {
        // 计算一下该服务对应的权限列表
        SERVICE = this.$route.meta.service
        const auths = ALL_AUTHORITYS[SERVICE]
        this.totalAuthoritys = auths.map(m => m.enName)
        this.roleFlag = this.loginerRole === MANAGER_ROLE_CODE ? '租户' : '用户'
        ORIGIN_AUTH_LIST = []
    },
    mounted() {
        this.getAuthInfo()
    },
    methods: {
        getTotalSubordinates() {
            const params = {
                isTenantGetTen: 2, // 非1表示获取当前登录者的下级用户，1表示获取租户列表
                resourceId: this.currentRow.resourceId,
                type: SERVICE,
            }
            this.subordinatesLoading = true
            authApi.getUserList(params)
            .then(res => {
                this.totalSubordinates = res.data || []
                this.subordinatesLoading = false
            }).catch(() => {
                this.subordinatesLoading = false
            })
        },
        getAuthInfo() {
            this.loading = true
            authApi.getAuthInfo({ type: SERVICE, id: this.currentRow.resourceId })
            .then(res => {
                this.currentUserAuth = res.data.currentUserAuth
                this.authList = (res.data.authList || []).map(a => {
                    if (!a.auth) {
                        a.auth = []
                    } else if (typeof a.auth === 'string') {
                        a.auth = a.auth.split('|')
                    }
                    a.authoritysCheckAll = a.auth.length === this.totalAuthoritys.length
                    return a
                })
                ORIGIN_AUTH_LIST = JSON.parse(JSON.stringify(this.authList))
                this.loading = false
            }).catch((err) => {
                if (err && err.code === API_ERROR_CODE) {
                    this.isNoRightToAssignAuth = true
                }
                this.loading = false
            })
        },
        handleDialogClose() {
            this.authList = []
            this.$emit('update:visible', false)
        },
        handleInnerDialogClose() {
            this.innerDialogVisible = false
            this.addSubordinatesForm = {
                subordinates: [],
                authoritys: [],
                authoritysCheckAll: false,
                isIndeterminate: false
            }
        },
        getUserFlag(role) {
            return LOGINER_FLAG_MAP[role] || this.roleFlag
        },
        onAddUser() {
            this.innerDialogVisible = true
            // 获取下级成员列表
            this.getTotalSubordinates()
        },
        onDeleteItem(i) {
            this.authList.splice(i, 1)
        },
        // 处理添加租户/用户弹窗权限全选/反全选
        handleAddSubAuthorityCheckAllChange(val) {
            this.addSubordinatesForm.isIndeterminate = false
            this.addSubordinatesForm.authoritys = val ? this.totalAuthoritys : []
        },
        // 处理添加租户/用户弹窗checkbox组权限变化的回调
        handleAddSubCheckedAuthorityChange(value) {
            const checkedCount = value.length
            this.addSubordinatesForm.authoritysCheckAll = checkedCount === this.totalAuthoritys.length
            this.addSubordinatesForm.isIndeterminate = checkedCount > 0 && checkedCount < this.totalAuthoritys.length
        },
        handleUserAuthChange(user) {
            if (user.auth.length === this.totalAuthoritys.length) {
                user.authoritysCheckAll = true
            } else {
                user.authoritysCheckAll = false
            }
        },
        // 确定添加分配权限的下级用户
        handleConformSubordinates() {
            let addList = []
            let subordinates = this.addSubordinatesForm.subordinates || []
            subordinates.forEach(userId => {
                let user = this.totalSubordinates.find(m => m.userId === userId)
                let item = {
                    id: null,
                    auth: this.addSubordinatesForm.authoritys,
                    userId,
                    userName: user.username
                }
                item.authoritysCheckAll = item.auth.length === this.totalAuthoritys.length
                addList.push(item)
            })
            this.authList.push(...addList)
            this.handleInnerDialogClose()
        },
        handleUserAuthorityCheckAllChange(user, i) {
            if (user.authoritysCheckAll) {
                user.auth = this.totalAuthoritys
            } else {
                user.auth = []
            }
        },
        // 提交权限分配
        async handleSubmit() {
            this.submiting = true
            const authList = this.authList.map(m => {
                let item = {}
                item.auth = m.auth && m.auth.length > 0 ? m.auth.join('|') : null
                item.userId = m.userId
                item.id = m.id
                return item
            })
            const param = {
                authList,
                id: this.currentRow.resourceId,
                type: SERVICE
            }
            await authApi.updateAuthInfo(param)
            this.$message({
                message: '权限分配成功',
                type: 'success'
            })
            this.submiting = false
            this.handleDialogClose()
            this.$emit('update')
        },
    }
}
</script>
<style lang="scss" scoped>
    @import '~@/styles/variables.scss';
    .select {
        width: 80%;
    }
    .authList-wrap {
        // padding-top: 30px;
        overflow-y: auto;
        .auth-item {
            border-bottom: 1px solid $lGray;
        }
    }
    .el-icon-delete {
        color: $blue;
        cursor: pointer;
        margin-left: 50px;
    }
    .no-use-assign-auth {
        color: $red;
        text-align: center;
        font-size: 16px;
    }
    .loading {
        width: 50px;
        height: 40px;
    }
</style>
